# -*- coding: utf-8 -*-

# tests/test_maker.py
# Part of ‘manpage’, a Python library for making Unix manual documents.
#
# Copyright © 2015–2016 Ben Finney <ben+python@benfinney.id.au>
#
# This is free software: see the grant of license at end of this file.

""" Unit tests for manual page maker behaviour. """

import sys
import os
import os.path
import distutils.dist
import textwrap
import unittest
import unittest.mock

__package__ = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
__import__(__package__)
sys.path.insert(1, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import manpage.document
import manpage.argparse_help
from .test_document import (
        setup_metadata_instance,
        )
from .test_argparse_help import (
        setup_parser_instance,
        TestArgumentParser,
        )


def setup_maker_instance(testcase, test_class=None, test_args=None):
    """ Set up a test `Maker` instance. """
    if test_class is None:
        test_class = testcase.maker_class
    if test_args is None:
        test_args = {}

    if 'metadata' not in test_args:
        setup_metadata_instance(testcase)
        test_args.update({
                'metadata': testcase.test_metadata_instance,
                })

    testcase.test_maker_instance = test_class(**test_args)


class ManPageMaker_TestCase(unittest.TestCase):
    """ Test cases for class `ManPageMaker`. """

    maker_class = manpage.document.ManPageMaker

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

        setup_maker_instance(self)

    def test_instantiate(self):
        """ An instance should be created. """
        self.assertIsInstance(self.test_maker_instance, self.maker_class)

    def test_document_class_is_expected_subclass(self):
        """ Should have `document_class` as expected subclass. """
        expected_superclass = manpage.document.Document
        self.assertTrue(issubclass(
                self.test_maker_instance.document_class, expected_superclass))


class ManPageMaker_make_manpage_TestCase(unittest.TestCase):
    """ Test cases for method `ManPageMaker.make_manpage`. """

    maker_class = manpage.document.ManPageMaker

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

        setup_maker_instance(self)

        self.patch_section_generators()

    def patch_section_generators(self):
        """ Patch the section generator functions for this test case. """
        function_names_by_title = {
                "NAME": 'make_name_section',
                "SYNOPSIS": 'make_synopsis_section',
                "DESCRIPTION": 'make_description_section',
                "SEE ALSO": 'make_seealso_section',
                }

        section_titles = function_names_by_title.keys()
        self.fake_sections = {title: object() for title in section_titles}

        for (section_title, method_name) in function_names_by_title.items():
            func_patcher = unittest.mock.patch.object(
                    self.maker_class, method_name, autospec=True)
            mock_func = func_patcher.start()
            self.addCleanup(func_patcher.stop)

            mock_func.return_value = self.fake_sections[section_title]

    def test_returns_instance_of_document_class(self):
        """ Should return an instance of `document_class`. """
        result = self.test_maker_instance.make_manpage()
        self.assertIsInstance(result, self.test_maker_instance.document_class)

    def test_document_has_specified_metadata(self):
        """ Should make document with specified `metadata`. """
        result = self.test_maker_instance.make_manpage()
        self.assertEqual(result.metadata, self.test_maker_instance.metadata)

    def test_document_has_generated_sections(self):
        """ Should make document with generated sections. """
        result = self.test_maker_instance.make_manpage()
        for (section_title, section) in self.fake_sections.items():
            with self.subTest(section=section_title):
                self.assertEqual(
                        result.content_sections[section_title], section)


class ManPageMaker_make_name_section_TestCase(unittest.TestCase):
    """ Test cases for method `ManPageMaker.make_name_section`. """

    maker_class = manpage.document.ManPageMaker

    scenarios = [
            ('simple', {
                'test_metadata': manpage.document.MetaData(
                    "lorem", "ipsum", None, None, None),
                'expected_body': textwrap.dedent("""\
                    lorem \\- ipsum
                    """),
                }),
            ('name-hyphenated', {
                'test_metadata': manpage.document.MetaData(
                    "foo-bar-baz", "ipsum", None, None, None),
                'expected_body': textwrap.dedent("""\
                    foo\\-bar\\-baz \\- ipsum
                    """),
                }),
            ('whatis-hyphenated', {
                'test_metadata': manpage.document.MetaData(
                    "lorem", "foo-bar-baz", None, None, None),
                'expected_body': textwrap.dedent("""\
                    lorem \\- foo\\[hy]bar\\[hy]baz
                    """),
                }),
            ]

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

        self.scenarios_by_name = dict(self.scenarios)

    def test_result_has_expected_title(self):
        """ Resulting section should have expected title. """
        setup_maker_instance(self)
        result = self.test_maker_instance.make_name_section()
        expected_title = "NAME"
        self.assertEqual(result.title, expected_title)

    def test_result_has_expected_body(self):
        """ Resulting section should have expected title. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                setup_maker_instance(self)
                self.test_maker_instance.metadata = scenario[
                    'test_metadata']
                result = self.test_maker_instance.make_name_section()
                self.assertEqual(result.body, scenario['expected_body'])


class ManPageMaker_make_synopsis_section_TestCase(unittest.TestCase):
    """ Test cases for method `ManPageMaker.make_synopsis_section`. """

    maker_class = manpage.document.ManPageMaker

    scenarios = [
            ('simple', {
                'test_args': {
                    'text': textwrap.dedent("""\
                        Lorem ipsum, dolor sit amet.
                        """),
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    Lorem ipsum, dolor sit amet.
                    """),
                }),
            ('text-unspecified', {
                'test_args': {},
                'expected_type': type(None),
                }),
            ('text-backslashes', {
                'test_args': {
                    'text': textwrap.dedent("""\
                        Lorem ipsum\\, dolor\\-sit amet.
                        """),
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    Lorem ipsum\\, dolor\\-sit amet.
                    """),
                }),
            ('text-hyphenated', {
                'test_args': {
                    'text': textwrap.dedent("""\
                        Lorem ipsum, dolor-sit-amet.
                        """),
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    Lorem ipsum, dolor-sit-amet.
                    """),
                }),
            ]

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

        self.scenarios_by_name = dict(self.scenarios)

    def test_result_is_instance_of_expected_type(self):
        """ Result should be an instance of expected type. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                setup_maker_instance(self)
                result = self.test_maker_instance.make_synopsis_section(
                        **scenario['test_args'])
                self.assertIsInstance(result, scenario['expected_type'])

    def test_result_has_expected_title(self):
        """ Resulting section should have expected title. """
        scenario = self.scenarios_by_name['simple']
        setup_maker_instance(self)
        result = self.test_maker_instance.make_synopsis_section(
                **scenario['test_args'])
        expected_title = "SYNOPSIS"
        self.assertEqual(result.title, expected_title)

    def test_result_has_expected_body(self):
        """ Resulting section should have expected body. """
        for (scenario_name, scenario) in (
                (name, scenario) for (name, scenario) in self.scenarios
                if scenario['test_args']):
            with self.subTest(scenario=scenario_name):
                setup_maker_instance(self)
                result = self.test_maker_instance.make_synopsis_section(
                        **scenario['test_args'])
                self.assertEqual(result.body, scenario['expected_body'])


class ManPageMaker_make_description_section_TestCase(unittest.TestCase):
    """ Test cases for method `ManPageMaker.make_description_section`. """

    maker_class = manpage.document.ManPageMaker

    scenarios = [
            ('simple', {
                'test_args': {
                    'text': textwrap.dedent("""\
                        Lorem ipsum, dolor sit amet.
                        """),
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    Lorem ipsum, dolor sit amet.
                    """),
                }),
            ('text-unspecified', {
                'test_args': {},
                'expected_type': type(None),
                }),
            ('text-backslashes', {
                'test_args': {
                    'text': textwrap.dedent("""\
                        Lorem ipsum\\, dolor\\-sit amet.
                        """),
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    Lorem ipsum\\[rs], dolor\\[rs]\\[hy]sit amet.
                    """),
                }),
            ('text-hyphenated', {
                'test_args': {
                    'text': textwrap.dedent("""\
                        Lorem ipsum, dolor-sit-amet.
                        """),
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    Lorem ipsum, dolor\\[hy]sit\\[hy]amet.
                    """),
                }),
            ]

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

        self.scenarios_by_name = dict(self.scenarios)

    def test_result_is_instance_of_expected_type(self):
        """ Result should be an instance of expected type. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                setup_maker_instance(self)
                result = self.test_maker_instance.make_description_section(
                        **scenario['test_args'])
                self.assertIsInstance(result, scenario['expected_type'])

    def test_result_has_expected_title(self):
        """ Resulting section should have expected title. """
        scenario = self.scenarios_by_name['simple']
        setup_maker_instance(self)
        result = self.test_maker_instance.make_description_section(
                **scenario['test_args'])
        expected_title = "DESCRIPTION"
        self.assertEqual(result.title, expected_title)

    def test_result_has_expected_body(self):
        """ Resulting section should have expected title. """
        for (scenario_name, scenario) in (
                (name, scenario) for (name, scenario) in self.scenarios
                if scenario['test_args']):
            with self.subTest(scenario=scenario_name):
                setup_maker_instance(self)
                result = self.test_maker_instance.make_description_section(
                        **scenario['test_args'])
                self.assertEqual(result.body, scenario['expected_body'])


class ManPageMaker_make_seealso_section_TestCase(unittest.TestCase):
    """ Test cases for method `ManPageMaker.make_seealso_section`. """

    maker_class = manpage.document.ManPageMaker

    scenarios = [
            ('references-missing', {
                'test_args': {},
                'expected_type': type(None),
                }),
            ('references-empty', {
                'test_args': {
                    'references': [],
                    },
                'expected_type': type(None),
                }),
            ('references-one,document', {
                'test_args': {
                    'references': [
                        manpage.document.DocumentReference.from_text(
                            "lorem(1)"),
                        ],
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    .BR lorem (1)
                    """),
                }),
            ('references-three,document', {
                'test_args': {
                    'references': [
                        manpage.document.DocumentReference.from_text(
                            "lorem(1)"),
                        manpage.document.DocumentReference.from_text(
                            "ipsum(8)"),
                        manpage.document.DocumentReference.from_text(
                            "dolor(6)"),
                        ],
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    .BR dolor (6),
                    .BR ipsum (8),
                    .BR lorem (1)
                    """),
                }),
            ('references-three,external', {
                'test_args': {
                    'references': [
                        manpage.document.ExternalReference(
                            "Lorem Ipsum"),
                        manpage.document.ExternalReference(
                            "Dolor Sit Amet", "spam://example.org/"),
                        manpage.document.ExternalReference(
                            "Nullam sed eleifend nibh", "spam://example.net/"),
                        ],
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    .UR spam://example.org/
                    Dolor Sit Amet
                    .UE ,
                    Lorem Ipsum,
                    .UR spam://example.net/
                    Nullam sed eleifend nibh
                    .UE
                    """),
                }),
            ('references-three,mixture', {
                'test_args': {
                    'references': [
                        manpage.document.DocumentReference.from_text(
                            "lorem(1)"),
                        manpage.document.ExternalReference(
                            "Dolor Sit Amet", "spam://example.org/"),
                        manpage.document.DocumentReference.from_text(
                            "nullam(6)"),
                        ],
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    .BR lorem (1),
                    .BR nullam (6),
                    .UR spam://example.org/
                    Dolor Sit Amet
                    .UE
                    """),
                }),
            ]

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

        self.scenarios_by_name = dict(self.scenarios)

    def test_result_is_instance_of_expected_type(self):
        """ Result should be an instance of expected type. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                setup_maker_instance(self)
                result = self.test_maker_instance.make_seealso_section(
                        **scenario['test_args'])
                self.assertIsInstance(result, scenario['expected_type'])

    def test_result_has_expected_title(self):
        """ Resulting section should have expected title. """
        scenario = self.scenarios_by_name['references-one,document']
        setup_maker_instance(self)
        result = self.test_maker_instance.make_seealso_section(
                **scenario['test_args'])
        expected_title = "SEE ALSO"
        self.assertEqual(result.title, expected_title)

    def test_result_has_expected_body(self):
        """ Resulting section should have expected body. """
        for (scenario_name, scenario) in (
                (scenario_name, scenario)
                for (scenario_name, scenario) in self.scenarios
                if 'expected_body' in scenario):
            with self.subTest(scenario=scenario_name):
                setup_maker_instance(self)
                result = self.test_maker_instance.make_seealso_section(
                        **scenario['test_args'])
                self.assertEqual(result.body, scenario['expected_body'])


class CommandManPageMaker_BaseTestCase(unittest.TestCase):
    """ Base class for test cases for class `CommandManPageMaker`. """

    maker_class = manpage.argparse_help.CommandManPageMaker
    parser_class = TestArgumentParser

    scenarios = NotImplemented

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

        if self.scenarios is not NotImplemented:
            self.scenarios_by_name = dict(self.scenarios)

        setup_parser_instance(
                self,
                test_args={'prog': "xyzzy"},
                test_actions=[])

        self.setup_maker_instance()

    def setup_maker_instance(self):
        """ Set up the `ManPageMaker` instance for this test case. """
        setup_maker_instance(self)
        self.test_maker_instance.set_parser(self.test_parser_instance)


class CommandManPageMaker_TestCase(CommandManPageMaker_BaseTestCase):
    """ Test cases for class `CommandManPageMaker`. """

    def test_instantiate(self):
        """ An instance should be created. """
        self.assertIsInstance(self.test_maker_instance, self.maker_class)

    def test_document_class_is_expected_subclass(self):
        """ Should have `document_class` as expected subclass. """
        expected_superclass = manpage.document.CommandDocument
        self.assertTrue(issubclass(
                self.test_maker_instance.document_class, expected_superclass))

    def test_has_specified_parser(self):
        """ Should have specified `parser` value. """
        self.assertIs(
                self.test_maker_instance.parser, self.test_parser_instance)


class CommandManPageMaker_set_parser_TestCase(
        CommandManPageMaker_BaseTestCase):
    """ Test cases for method `CommandManPageMaker.set_parser`. """

    def test_has_specified_parser(self):
        """ Should have specified `parser` value. """
        self.assertIs(
                self.test_maker_instance.parser, self.test_parser_instance)

    def test_parser_has_expected_formatter_class(self):
        """ Parser should have expected `formatter_class` value. """
        expected_class = manpage.argparse_help.ManPageHelpFormatter
        self.assertIs(
                self.test_maker_instance.parser.formatter_class,
                expected_class)

    def test_parser_has_expected_command_name(self):
        """ Parser should have expected command name as `prog` value. """
        expected_name = self.test_metadata_instance.name
        self.assertEqual(
                self.test_maker_instance.parser.prog, expected_name)


class CommandManPageMaker_make_synopsis_section_TestCase(
        CommandManPageMaker_BaseTestCase):
    """ Test cases for method `CommandManPageMaker.make_synopsis_section`. """

    fake_usage_output = textwrap.dedent("""\
            Quisque faucibus ipsum
            tincidunt commodo interdum.
            """)

    scenarios = [
            ('simple', {
                'test_args': {
                    'text': textwrap.dedent("""\
                        Lorem ipsum, dolor sit amet.
                        """),
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    Lorem ipsum, dolor sit amet.
                    """),
                }),
            ('text-unspecified', {
                'test_args': {},
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    Quisque faucibus ipsum tincidunt commodo interdum.
                    """),
                }),
            ]

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

        self.patch_parser_format_usage()

    def patch_parser_format_usage(self):
        """ Patch the parser `format_usage` method for this test case. """
        func_patcher = unittest.mock.patch.object(
                self.test_parser_instance, 'format_usage')
        mock_func = func_patcher.start()
        self.addCleanup(func_patcher.stop)

        mock_func.return_value = self.fake_usage_output

    def test_result_is_instance_of_expected_type(self):
        """ Result should be an instance of expected type. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                self.setup_maker_instance()
                result = self.test_maker_instance.make_synopsis_section(
                        **scenario['test_args'])
                self.assertIsInstance(result, scenario['expected_type'])

    def test_result_has_expected_title(self):
        """ Resulting section should have expected title. """
        scenario = self.scenarios_by_name['simple']
        self.setup_maker_instance()
        result = self.test_maker_instance.make_synopsis_section(
                **scenario['test_args'])
        expected_title = "SYNOPSIS"
        self.assertEqual(result.title, expected_title)

    def test_result_has_expected_body(self):
        """ Resulting section should have expected body. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                self.setup_maker_instance()
                result = self.test_maker_instance.make_synopsis_section(
                        **scenario['test_args'])
                self.assertEqual(result.body, scenario['expected_body'])


class CommandManPageMaker_make_description_section_TestCase(
        CommandManPageMaker_BaseTestCase):
    """ Test cases for `CommandManPageMaker.make_description_section`. """

    fake_parser_description = textwrap.dedent("""\
            Quisque faucibus ipsum
            tincidunt commodo interdum.
            """)

    scenarios = [
            ('simple', {
                'test_args': {
                    'text': textwrap.dedent("""\
                        Lorem ipsum, dolor sit amet.
                        """),
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    Lorem ipsum, dolor sit amet.
                    """),
                }),
            ('text-unspecified', {
                'test_args': {},
                'expected_type': manpage.document.DocumentSection,
                'expected_body': fake_parser_description,
                }),
            ]

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

        self.test_parser_instance.description = self.fake_parser_description

    def test_result_is_instance_of_expected_type(self):
        """ Result should be an instance of expected type. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                self.setup_maker_instance()
                result = self.test_maker_instance.make_description_section(
                        **scenario['test_args'])
                self.assertIsInstance(result, scenario['expected_type'])

    def test_result_has_expected_title(self):
        """ Resulting section should have expected title. """
        scenario = self.scenarios_by_name['simple']
        self.setup_maker_instance()
        result = self.test_maker_instance.make_description_section(
                **scenario['test_args'])
        expected_title = "DESCRIPTION"
        self.assertEqual(result.title, expected_title)

    def test_result_has_expected_body(self):
        """ Resulting section should have expected body. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                self.setup_maker_instance()
                result = self.test_maker_instance.make_description_section(
                        **scenario['test_args'])
                self.assertEqual(result.body, scenario['expected_body'])


class CommandManPageMaker_make_options_section_TestCase(
        CommandManPageMaker_BaseTestCase):
    """ Test cases for `CommandManPageMaker.make_options_section`. """

    fake_options_output = textwrap.dedent("""\
            Quisque faucibus ipsum
            tincidunt commodo interdum.
            """)

    scenarios = [
            ('simple', {
                'expected_type': manpage.document.DocumentSection,
                'expected_body': fake_options_output,
                }),
            ]

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

        formatter_class = manpage.argparse_help.ManPageHelpFormatter
        self.test_parser_instance.formatter_class = formatter_class

        self.patch_parser_formatter_format_options()

    def patch_parser_formatter_format_options(self):
        """ Patch the formatter `format_options` method for this test case. """
        func_patcher = unittest.mock.patch.object(
                self.test_parser_instance.formatter_class, 'format_options')
        mock_func = func_patcher.start()
        self.addCleanup(func_patcher.stop)

        mock_func.return_value = self.fake_options_output

    def test_result_is_instance_of_expected_type(self):
        """ Result should be an instance of expected type. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                self.setup_maker_instance()
                result = self.test_maker_instance.make_options_section()
                self.assertIsInstance(result, scenario['expected_type'])

    def test_result_has_expected_title(self):
        """ Resulting section should have expected title. """
        scenario = self.scenarios_by_name['simple']
        self.setup_maker_instance()
        result = self.test_maker_instance.make_options_section()
        expected_title = "OPTIONS"
        self.assertEqual(result.title, expected_title)

    def test_result_has_expected_body(self):
        """ Resulting section should have expected body. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                self.setup_maker_instance()
                result = self.test_maker_instance.make_options_section()
                self.assertEqual(result.body, scenario['expected_body'])


class CommandManPageMaker_make_distribution_section_TestCase(
        CommandManPageMaker_BaseTestCase):
    """ Test cases for `CommandManPageMaker.make_distribution_section`. """

    scenarios = [
            ('simple', {
                'test_args': {
                    'distribution': distutils.dist.Distribution(
                        attrs={
                            'name': "lorem-ipsum",
                            'url': "dolor-sit-amet",
                            }),
                    },
                'expected_type': manpage.document.DocumentSection,
                'expected_body': textwrap.dedent("""\
                    The command
                    .B lorem
                    is part of the Python distribution
                    \\[lq]lorem\\[hy]ipsum\\[rq].
                    The home page for lorem\\[hy]ipsum is at
                    .UR dolor\\[hy]sit\\[hy]amet
                    .UE .
                    """),
                }),
            ]

    def setUp(self):
        """ Set up test fixtures. """
        super().setUp()

    def test_result_is_instance_of_expected_type(self):
        """ Result should be an instance of expected type. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                self.setup_maker_instance()
                result = self.test_maker_instance.make_distribution_section(
                        **scenario['test_args'])
                self.assertIsInstance(result, scenario['expected_type'])

    def test_result_has_expected_title(self):
        """ Resulting section should have expected title. """
        scenario = self.scenarios_by_name['simple']
        self.setup_maker_instance()
        result = self.test_maker_instance.make_distribution_section(
                **scenario['test_args'])
        expected_title = "DISTRIBUTION"
        self.assertEqual(result.title, expected_title)

    def test_result_has_expected_body(self):
        """ Resulting section should have expected body. """
        for (scenario_name, scenario) in self.scenarios:
            with self.subTest(scenario=scenario_name):
                self.setup_maker_instance()
                result = self.test_maker_instance.make_distribution_section(
                        **scenario['test_args'])
                self.assertEqual(result.body, scenario['expected_body'])


class CommandManPageMaker_make_manpage_TestCase(
        ManPageMaker_make_manpage_TestCase):
    """ Test cases for `CommandManPageMaker.make_manpage`. """

    maker_class = manpage.argparse_help.CommandManPageMaker

    def patch_section_generators(self):
        """ Patch the section generator functions for this test case. """
        function_names_by_title = {
                "NAME": 'make_name_section',
                "SYNOPSIS": 'make_synopsis_section',
                "DESCRIPTION": 'make_description_section',
                "OPTIONS": 'make_options_section',
                "SEE ALSO": 'make_seealso_section',
                }

        section_titles = function_names_by_title.keys()
        self.fake_sections = {title: object() for title in section_titles}

        for (section_title, method_name) in function_names_by_title.items():
            func_patcher = unittest.mock.patch.object(
                    self.maker_class, method_name, autospec=True)
            mock_func = func_patcher.start()
            self.addCleanup(func_patcher.stop)

            mock_func.return_value = self.fake_sections[section_title]


# This is free software: you may copy, modify, and/or distribute this work
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; version 3 of that license or any later version.
#
# No warranty expressed or implied. See the file ‘LICENSE.GPL-3’ for details,
# or view it online at <URL:https://www.gnu.org/licenses/gpl-3.0.html>.


# Local variables:
# coding: utf-8
# mode: python
# End:
# vim: fileencoding=utf-8 filetype=python :
